/*
 * Copyright (C) 2006-2010 - Frictional Games
 *
 * This file is part of Penumbra Overture.
 *
 * Penumbra Overture is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Penumbra Overture is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Penumbra Overture.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "GameEnemy_Dog.h"


#include "Player.h"
#include "AttackHandler.h"
#include "EffectHandler.h"
#include "GameMusicHandler.h"
#include "GameSwingDoor.h"
#include "MapHandler.h"

//////////////////////////////////////////////////////////////////////////
// BASE STATE
//////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------

iGameEnemyState_Dog_Base::iGameEnemyState_Dog_Base(int alId, cInit *apInit, iGameEnemy *apEnemy)
							: iGameEnemyState(alId,apInit,apEnemy)
{	
	mpEnemyDog = static_cast<cGameEnemy_Dog*>(mpEnemy);
}

//-----------------------------------------------------------------------

void iGameEnemyState_Dog_Base::OnSeePlayer(const cVector3f &avPosition, float afChance)
{
	//return;
	if(mpPlayer->GetHealth() <=0) return;

	if(afChance >= mpEnemyDog->mfIdleMinSeeChance)
	{
		/*if( (mlId == STATE_IDLE || mlId == STATE_INVESTIGATE || mlId == STATE_PATROL) &&
			cMath::RandRectf(0,1) < mpEnemyDog->mfIdleCallBackupChance && 
			mpEnemy->CheckForTeamMate(8,true)==false)
		{
			mpEnemy->ChangeState(STATE_CALLBACKUP);
		}
		else
		{
			//mpEnemy->ChangeState(STATE_HUNT);
			//mpEnemyDog->PlaySound(mpEnemyDog->msIdleFoundPlayerSound);	
		}*/

		float fDist = cMath::Vector3Dist(mpMover->GetCharBody()->GetFeetPosition(),
										mpPlayer->GetCharacterBody()->GetFeetPosition());
		if(fDist >= mpEnemyDog->mfAttentionMinDist)
		{
			mpEnemy->ChangeState(STATE_ATTENTION);
		}
		else
		{
			mpEnemy->ChangeState(STATE_HUNT);
			mpEnemyDog->PlaySound(mpEnemyDog->msIdleFoundPlayerSound);	
		}

	}
}

bool iGameEnemyState_Dog_Base::OnHearNoise(const cVector3f &avPosition, float afVolume)
{
	//return false;
	float afDistance = (mpMover->GetCharBody()->GetPosition() - avPosition).Length();

	if(afVolume >= mpEnemyDog->mfIdleMinHearVolume && afDistance > 0.4f)
	{
		mpEnemy->SetTempPosition(avPosition);
		mpEnemy->ChangeState(STATE_INVESTIGATE);
		return true;
	}

	return false;
}

void iGameEnemyState_Dog_Base::OnTakeHit(float afDamage)
{
	if(afDamage >= mpEnemyDog->mfMinKnockDamage)
	{
		if(mpInit->mbWeaponAttacking)
		{
			float fChance = afDamage / mpEnemyDog->mfCertainKnockDamage;//(mpEnemyDog->mfCertainKnockDamage*4);
			if(fChance > cMath::RandRectf(0,1))
			{
				mpEnemy->ChangeState(STATE_KNOCKDOWN);
			}
		}
		else
		{
			if(afDamage >= mpEnemyDog->mfCertainKnockDamage)
			{
				mpEnemy->ChangeState(STATE_KNOCKDOWN);
			}
			else
			{
				float fChance = afDamage / mpEnemyDog->mfCertainKnockDamage;
				if(fChance > cMath::RandRectf(0,1))
				{
					mpEnemy->ChangeState(STATE_KNOCKDOWN);
				}
			}
		}
	}
}

void iGameEnemyState_Dog_Base::OnFlashlight(const cVector3f &avPosition)
{
	//mpInit->mpEffectHandler->GetSubTitle()->Add("Flashlight!",0.5f,true);
	//OnSeePlayer(mpPlayer->GetCharacterBody()->GetFeetPosition(),1.0f);
	
	//mpEnemy->SetLastPlayerPos(mpPlayer->GetCharacterBody()->GetFeetPosition());
	//mpEnemy->ChangeState(STATE_HUNT);

	mpEnemy->SetTempPosition(avPosition);
	mpEnemy->ChangeState(STATE_INVESTIGATE);
}

void iGameEnemyState_Dog_Base::OnDeath(float afDamage)
{
	mpEnemy->ChangeState(STATE_DEAD);
}

//-----------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////
// IDLE STATE
//////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Idle::OnEnterState(iGameEnemyState *apPrevState)
{
	//Animation
	mpEnemy->UseMoveStateAnimations();

	//Setup body
	mpEnemy->SetupBody();

	//Setup enemy
	mpEnemy->SetFOV(mpEnemyDog->mfIdleFOV);

	mpInit->mpMusicHandler->RemoveAttacker(mpEnemy);
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Idle::OnLeaveState(iGameEnemyState *apNextState)
{
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Idle::OnUpdate(float afTimeStep)
{
	if(mpEnemy->GetPatrolNodeNum()>0)
	{
		mpEnemy->ChangeState(STATE_PATROL);
	}
}

//-----------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////
// PATROL STATE
//////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Patrol::OnEnterState(iGameEnemyState *apPrevState)
{
	//Animation
	mpEnemy->UseMoveStateAnimations();

	//Setup body
	mpEnemy->SetupBody();

	//Setup enemy
	mpEnemy->SetFOV(mpEnemyDog->mfIdleFOV);

	//Setup patrol
	cEnemyPatrolNode *pPatrolNode = mpEnemy->CurrentPatrolNode();
	cAINode *pNode = mpMover->GetNodeContainer()->GetNodeFromName(pPatrolNode->msNodeName);

	if(mpEnemy->GetDoorBreakCount()> 3.0f)
	{
		mpEnemy->SetDoorBreakCount(0);
		mpMover->SetMaxDoorToughness(0);
	}

	mbWaiting = false;
	mbAnimation = false;
	mlStuckAtMaxCount =0;


	mfIdleSoundTime = cMath::RandRectf(	mpEnemyDog->mfIdleSoundMinInteraval,
										mpEnemyDog->mfIdleSoundMaxInteraval);

	mpMover->SetMaxDoorToughness(-1);

	if(mpMover->MoveToPos(pNode->GetPosition())==false)
	{
		//tString sStr = "Could not get to path node "+pPatrolNode->msNodeName;
		//mpInit->mpEffectHandler->GetSubTitle()->Add(sStr,3,true);
		
		mpEnemy->IncCurrentPatrolNode();
		mbWaiting = true;
		mpEnemy->SetWaitTime(1.0f);
	}
	else
	{
		//tString sStr = "Moving to path node "+pPatrolNode->msNodeName;
		//mpInit->mpEffectHandler->GetSubTitle()->Add(sStr,3,true);
	}
	
	
	mpInit->mpMusicHandler->RemoveAttacker(mpEnemy);
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Patrol::OnLeaveState(iGameEnemyState *apNextState)
{
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Patrol::OnUpdate(float afTimeStep)
{	
	/////////////////////////////////
	//Waiting for timer or animation to end
	if(mbWaiting)
	{
		//////////////////////////////
		//Play idle sound
		if(mfIdleSoundTime<=0)
		{
			mfIdleSoundTime = cMath::RandRectf(	mpEnemyDog->mfIdleSoundMinInteraval,
				mpEnemyDog->mfIdleSoundMaxInteraval);

			mpEnemy->PlaySound(mpEnemyDog->msIdleSound);
		}
		else
		{
			mfIdleSoundTime -= afTimeStep;
		}

		//////////////////////////////
		// Timer is up
		if(mpEnemy->GetWaitTimeCount() >= mpEnemy->GetWaitTime())
		{
			if(mbAnimation==false)
			{
				mpEnemy->SetWaitTimeCount(0);
				cEnemyPatrolNode *pPatrolNode = mpEnemy->CurrentPatrolNode();
				cAINode *pNode = mpMover->GetNodeContainer()->GetNodeFromName(pPatrolNode->msNodeName);
				
				mpEnemy->UseMoveStateAnimations();
				mbWaiting = false;
				
				if(mpMover->MoveToPos(pNode->GetPosition())==false)
				{
					//tString sStr = "Could not get to path node "+pPatrolNode->msNodeName;
					//mpInit->mpEffectHandler->GetSubTitle()->Add(sStr,3,false);
					mpEnemy->IncCurrentPatrolNode();
					mbWaiting = true;
					mpEnemy->SetWaitTime(1.0f);
				}
				else
				{
					//tString sStr = "Moving to path node "+pPatrolNode->msNodeName;
					//mpInit->mpEffectHandler->GetSubTitle()->Add(sStr,3,false);
				}
				
			}
			else
			{
				mpEnemy->GetCurrentAnimation()->SetLoop(false);
			}
		}
		else
		{
			mpEnemy->AddWaitTimeCount(afTimeStep);
		}
	}
	/////////////////////////////////
	//Check if path is over
	else
	{
		//////////////////////////////
		//Play idle sound
		if(mfIdleSoundTime<=0)
		{
			mfIdleSoundTime = cMath::RandRectf(	mpEnemyDog->mfIdleSoundMinInteraval,
												mpEnemyDog->mfIdleSoundMaxInteraval);

			mpEnemy->PlaySound(mpEnemyDog->msIdleSound);
		}
		else
		{
			mfIdleSoundTime -= afTimeStep;
		}

		//////////////////////////////
		//Stuck counter
		if(mpMover->GetStuckCounter() > 1.7f)
		{
			if(mpEnemy->CheckForDoor())
			{
				mpEnemy->ChangeState(STATE_BREAKDOOR);
			}
			else
			{
				mlStuckAtMaxCount++;
				if(mlStuckAtMaxCount >= 6)
				{
					mpEnemy->ChangeState(STATE_IDLE);
					mpEnemy->SetWaitTime(1.0f);
					mpEnemy->IncCurrentPatrolNode();
				}
			}
			mpMover->ResetStuckCounter();
		}

		//////////////////////////////
		//Got to ned of path
		if(mpMover->IsMoving()==false)
		{
			cEnemyPatrolNode *pPatrolNode = mpEnemy->CurrentPatrolNode();

			mpEnemy->SetWaitTime(pPatrolNode->mfWaitTime);
			mpEnemy->IncCurrentPatrolNode();
            
			if(pPatrolNode->msAnimation != "")
			{
				mpEnemy->PlayAnim(pPatrolNode->msAnimation,true,0.2f);
				mbAnimation = true;
			}

			mbWaiting = true;
		}
	}
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Patrol::OnAnimationOver(const tString &asName)
{
	mbAnimation = false;
}

//////////////////////////////////////////////////////////////////////////
// ATTENTION STATE
//////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Attention::OnEnterState(iGameEnemyState *apPrevState)
{
	//Animation
	mpEnemy->PlayAnim("Angry",true,0.2f);


	//Setup body
	mpEnemy->SetupBody();

	//Setup enemy
	mpEnemy->SetFOV(mpEnemyDog->mfIdleFOV);

	mpMover->Stop();
	mpMover->TurnToPos(mpPlayer->GetCharacterBody()->GetFeetPosition());

	mpEnemy->PlaySound(mpEnemyDog->msAttentionSound);	
	mfTime = mpEnemyDog->mfAttentionTime;
	
#ifndef DEMO_VERSION
	if(mpInit->mDifficulty == eGameDifficulty_Easy) mfTime *=1.7f;
	if(mpInit->mbHasHaptics) mfTime *= 1.3f;

#endif
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Attention::OnLeaveState(iGameEnemyState *apNextState)
{
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Attention::OnUpdate(float afTimeStep)
{
	mpMover->TurnToPos(mpPlayer->GetCharacterBody()->GetFeetPosition());
	mfTime -= afTimeStep;

	if(mfTime <=0)
	{
		if(mpEnemy->CanSeePlayer())
		{
			mpEnemy->ChangeState(STATE_HUNT);
			mpEnemy->PlaySound(mpEnemyDog->msIdleFoundPlayerSound);	
		}
		else
		{
			if(mlPreviousState == STATE_ATTENTION)
				mpEnemy->ChangeState(STATE_IDLE);
			else
				mpEnemy->ChangeState(mlPreviousState);
		}
	}

}

//-----------------------------------------------------------------------


void cGameEnemyState_Dog_Attention::OnSeePlayer(const cVector3f &avPosition, float afChance)
{

}
bool cGameEnemyState_Dog_Attention::OnHearNoise(const cVector3f &avPosition, float afVolume)
{
	return false;
}
void cGameEnemyState_Dog_Attention::OnFlashlight(const cVector3f &avPosition)
{
	mpEnemy->ChangeState(STATE_HUNT);
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Attention::OnDraw()
{

}

//-----------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////
// EAT STATE
//////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Eat::OnEnterState(iGameEnemyState *apPrevState)
{
	//Animation
	mpEnemy->PlayAnim("Eating",true,0.2f);

	//Setup body
	mpEnemy->SetupBody();

	//Setup enemy
	mpEnemy->SetFOV(mpEnemyDog->mfEatFOV);

	mfTime = mpEnemy->GetTempFloat();

	mpMover->GetCharBody()->SetMoveSpeed(eCharDir_Forward,0);
	mpMover->Stop();
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Eat::OnLeaveState(iGameEnemyState *apNextState)
{
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Eat::OnUpdate(float afTimeStep)
{	
	mfTime -= afTimeStep;
	if(mfTime <=0)
	{
		mpEnemy->ChangeState(mlPreviousState);//STATE_IDLE);
	}
}

//-----------------------------------------------------------------------

bool cGameEnemyState_Dog_Eat::OnHearNoise(const cVector3f &avPosition, float afVolume)
{
	//return false;
	if(	afVolume >= mpEnemyDog->mfEatMinHearVolume)
	{
		mpEnemy->SetTempPosition(avPosition);
		mpEnemy->ChangeState(STATE_INVESTIGATE);
		return true;
	}

	return false;
}

void cGameEnemyState_Dog_Eat::OnSeePlayer(const cVector3f &avPosition, float afChance)
{
	//return;
	if(mpPlayer->GetHealth() <=0) return;

	if(afChance >= mpEnemyDog->mfEatMinSeeChance)
	{
		mpEnemy->ChangeState(STATE_HUNT);
		mpEnemyDog->PlaySound(mpEnemyDog->msIdleFoundPlayerSound);
	}
}

//-----------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////
// INVESTIGATE STATE
//////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Investigate::OnEnterState(iGameEnemyState *apPrevState)
{
	//Animation
	mpEnemy->UseMoveStateAnimations();

	//Setup body
	mpEnemy->SetupBody();

	//Setup enemy
	mpEnemy->SetFOV(mpEnemyDog->mfIdleFOV);

	//Play sound
	mpEnemy->PlaySound(mpEnemyDog->msInvestigateSound);

	cAINode *pNode = mpMover->GetAINodeAtPosInRange(mpEnemy->GetTempPosition(),0.0f,5.0f,true, 0.1f);

	if(mpEnemy->GetDoorBreakCount()> 6.0f)
	{
		mpEnemy->SetDoorBreakCount(0);
		mpMover->SetMaxDoorToughness(0);
	}
	
	if(pNode)
	{
		if(mpMover->MoveToPos(pNode->GetPosition())==false)
		{
			mpEnemy->ChangeState(STATE_IDLE);
		}
	}
	else
	{
		mpEnemy->ChangeState(STATE_IDLE);
	}

	mpMover->SetMaxDoorToughness(-1);

	mpInit->mpMusicHandler->RemoveAttacker(mpEnemy);

	mfIdleSoundTime = cMath::RandRectf(	mpEnemyDog->mfIdleSoundMinInteraval,
										mpEnemyDog->mfIdleSoundMaxInteraval);

	if(apPrevState->GetId() != STATE_INVESTIGATE)
	{
		mfHighestVolume = 0.0f;
	}

	mfHearSoundCount = 5.0f;
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Investigate::OnLeaveState(iGameEnemyState *apNextState)
{
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Investigate::OnUpdate(float afTimeStep)
{	
	if(mfHearSoundCount >0){
		mfHearSoundCount-=afTimeStep;
		if(mfHearSoundCount<=0)mfHearSoundCount=0;
	}

	////////////////////////////////
	//Play idle sound
	if(mfIdleSoundTime<=0)
	{
		mfIdleSoundTime = cMath::RandRectf(	mpEnemyDog->mfIdleSoundMinInteraval,
			mpEnemyDog->mfIdleSoundMaxInteraval);

		mpEnemy->PlaySound(mpEnemyDog->msIdleSound);
	}
	else
	{
		mfIdleSoundTime -= afTimeStep;
	}

	////////////////////////////////
	//Stuck counter
	if(mpMover->GetStuckCounter() > 1.5f)
	{
		if(mlKnockCount == 1){
			mpEnemy->ChangeState(STATE_IDLE);
			mlKnockCount =0;
		}
		else
		{
			if(mpEnemy->CheckForDoor())
			{
				mpEnemy->ChangeState(STATE_BREAKDOOR);
			}
			mpMover->ResetStuckCounter();
			mlKnockCount++;
		}
	}

	if(mpMover->IsMoving()==false)
	{
		mlKnockCount =0;
		mpEnemy->ChangeState(STATE_IDLE);
	}
}

//-----------------------------------------------------------------------

bool cGameEnemyState_Dog_Investigate::OnHearNoise(const cVector3f &avPosition, float afVolume)
{
	if(	mfHearSoundCount<=0 && mfHighestVolume < afVolume &&
		afVolume >= mpEnemyDog->mfIdleMinHearVolume)
	{
		mfHighestVolume = afVolume;
		mpEnemy->SetTempPosition(avPosition);
		OnEnterState(this);

		return true;
	}

	return false;
}

//-----------------------------------------------------------------------


//////////////////////////////////////////////////////////////////////////
// MOVE TO STATE
//////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_MoveTo::OnEnterState(iGameEnemyState *apPrevState)
{
	//Animation
	mpEnemy->UseMoveStateAnimations();

	//Setup body
	mpEnemy->SetupBody();

	//Setup enemy
	mpEnemy->SetFOV(mpEnemyDog->mfIdleFOV);

	//Play sound
	mpEnemy->PlaySound(mpEnemyDog->msInvestigateSound);
	
	if(mpMover->MoveToPos(mpEnemy->GetTempPosition())==false)
	{
		//mpInit->mpEffectHandler->GetSubTitle()->Add("Could not move to pos!\n",3,true);
		mpEnemy->ChangeState(apPrevState->GetId());
		return;
	}
	else
	{
		//mpInit->mpEffectHandler->GetSubTitle()->Add("Moving to pos!\n",3,true);
	}
	
	mpInit->mpMusicHandler->RemoveAttacker(mpEnemy);

	mfIdleSoundTime = cMath::RandRectf(	mpEnemyDog->mfIdleSoundMinInteraval,
										mpEnemyDog->mfIdleSoundMaxInteraval);

	mlBreakCount = 0;
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_MoveTo::OnLeaveState(iGameEnemyState *apNextState)
{
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_MoveTo::OnUpdate(float afTimeStep)
{	
	////////////////////////////////
	//Play idle sound
	if(mfIdleSoundTime<=0)
	{
		mfIdleSoundTime = cMath::RandRectf(	mpEnemyDog->mfIdleSoundMinInteraval,
			mpEnemyDog->mfIdleSoundMaxInteraval);

		mpEnemy->PlaySound(mpEnemyDog->msIdleSound);
	}
	else
	{
		mfIdleSoundTime -= afTimeStep;
	}

	////////////////////////////////
	//Stuck counter
	if(mpMover->GetStuckCounter() > 1.5f)
	{
		if(mlBreakCount ==1)
		{
			mpEnemy->ChangeState(STATE_IDLE);
		}
		else
		{
			if(mpEnemy->CheckForDoor())
			{
				mpEnemy->ChangeState(STATE_BREAKDOOR);
			}
			mpMover->ResetStuckCounter();
			mlBreakCount++;
		}
	}

	if(mpMover->IsMoving()==false)
	{
		mpEnemy->ChangeState(STATE_IDLE);
	}
}

//-----------------------------------------------------------------------


//////////////////////////////////////////////////////////////////////////
// HUNT STATE
//////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Hunt::OnEnterState(iGameEnemyState *apPrevState)
{
	//Animation
	mpEnemy->UseMoveStateAnimations();

	//Setup body
	mpEnemy->SetupBody();

#ifndef DEMO_VERSION
	float fMul = 1.0f;
	if(mpInit->mbHasHaptics) fMul = 0.6f;

	if(mpInit->mDifficulty == eGameDifficulty_Easy)
		mpMover->GetCharBody()->SetMaxPositiveMoveSpeed(eCharDir_Forward,mpEnemyDog->mfHuntSpeed*0.7f*fMul);
	else if(mpInit->mDifficulty == eGameDifficulty_Normal)
		mpMover->GetCharBody()->SetMaxPositiveMoveSpeed(eCharDir_Forward,mpEnemyDog->mfHuntSpeed*fMul);
	else 
		mpMover->GetCharBody()->SetMaxPositiveMoveSpeed(eCharDir_Forward,mpEnemyDog->mfHuntSpeed*1.25f*fMul);
#else
	mpMover->GetCharBody()->SetMaxPositiveMoveSpeed(eCharDir_Forward,mpEnemyDog->mfHuntSpeed);
#endif


	//Setup enemy
	mpEnemy->SetFOV(mpEnemyDog->mfHuntFOV);

	mfUpdatePathCount =0;
	mfUpdateFreq = 1.0f;
	mbFreePlayerPath = false;
	
	if(mbBreakingDoor && mpEnemy->CanSeePlayer()==false)
	{
		mlBreakDoorCount++;
		if(mlBreakDoorCount>=3)
		{
			mpEnemy->ChangeState(STATE_IDLE);
			return;
		}
	}
	else
	{
		mlBreakDoorCount =0;
	}
	
	mbBreakingDoor = false;
	mbFoundNoPath = false;
	mbLostPlayer = false;
	mfLostPlayerCount =0;	
	mfMaxLostPlayerCount = mpEnemyDog->mfHuntForLostPlayerTime;

	mlStuckAtMaxCount =0;

    mpInit->mpMusicHandler->AddAttacker(mpEnemy);
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Hunt::OnLeaveState(iGameEnemyState *apNextState)
{
	mpMover->SetMaxDoorToughness(-1);
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Hunt::OnUpdate(float afTimeStep)
{
	if(mpPlayer->GetHealth() <=0){
		mpEnemy->ChangeState(STATE_IDLE);
		return;
	}

	if(mpMover->GetStuckCounter() > 1.1f)
	{
		if(mpEnemy->CheckForDoor())
		{
			mbBreakingDoor = true;
			mpEnemy->ChangeState(STATE_BREAKDOOR);
		}
		else
		{
			mlStuckAtMaxCount++;
			if(mlStuckAtMaxCount >= 6)
			{
				mpEnemy->ChangeState(STATE_IDLE);
			}
		}
		mpMover->ResetStuckCounter();
	}

	if(mfUpdatePathCount <=0)
	{
		mbFoundNoPath = false;
		//mpInit->mpEffectHandler->GetSubTitle()->Add("Update Path!",1.0f,true);
		mfUpdatePathCount = mfUpdateFreq;
		
		cAINodeContainer *pNodeCont = mpEnemy->GetMover()->GetNodeContainer();

		//Log("%s: Checking free path\n",mpEnemy->GetName().c_str());
		
		//Check if there is a free path to the player
		if(mbLostPlayer == false && mpMover->FreeDirectPathToChar(mpPlayer->GetCharacterBody()))
		{
			mbFreePlayerPath = true;
			mpMover->Stop();
			mpMover->SetMaxDoorToughness(-1);
		}
		else
		{
			mbFreePlayerPath = false;
		}
		
		//Get path to player
		if(mbFreePlayerPath==false && mbLostPlayer == false)
		{
			if(mpEnemy->GetDoorBreakCount()> 6.0f)
			{
				mpMover->SetMaxDoorToughness(0);
			}

			//Log("%s: Move to pos\n",mpEnemy->GetName().c_str());

			if(mpMover->MoveToPos(mpEnemy->GetLastPlayerPos())==false)
			{
				bool bFoundAnotherWay = false;
				/*float fHeight = mpMover->GetCharBody()->GetPosition().y -
								mpPlayer->GetCharacterBody()->GetPosition().y;
				if(cMath::Abs(fHeight) > mpMover->GetNodeContainer()->GetMaxHeight())
				{
					cVector3f vPos = mpEnemy->GetLastPlayerPos();
					vPos.y = mpMover->GetCharBody()->GetFeetPosition().y+0.1f;

					if(mpMover->MoveToPos(vPos))
					{
						bFoundAnotherWay = true;
					}
				}*/
				
				if(bFoundAnotherWay == false)
				{
					mfUpdatePathCount = mfUpdateFreq*5.0f;
					mpMover->Stop();
					//Set this so the enemey at least runs toward the player.
					mbFoundNoPath = true;
				}
			}

			//Log("%s: Done with that.\n",mpEnemy->GetName().c_str());
		}
	}
	else
	{
		mfUpdatePathCount -= afTimeStep;
	}
	
	////////////////////////////////
	//Go directly towards the player
	if(mbFreePlayerPath || (mbFoundNoPath && mpMover->IsMoving()==false))
	{
		//Go towards player
		mpMover->MoveDirectToPos(mpPlayer->GetCharacterBody()->GetFeetPosition(),afTimeStep);
		
        //Check if he should attack.
		if(mpMover->DistanceToChar2D(mpPlayer->GetCharacterBody()) < mpEnemyDog->mfAttackDistance)
		{
			float fHeight = mpMover->GetCharBody()->GetPosition().y -
							mpPlayer->GetCharacterBody()->GetPosition().y;
			
			//Player is above
			if(fHeight < 0)
			{
				fHeight += mpMover->GetCharBody()->GetSize().y/2.0f;
				float fMax = mpEnemyDog->mvAttackDamageSize.y;///2.0f;
				if(fHeight > -fMax)	
				{
					mpEnemy->ChangeState(STATE_ATTACK);
				}
				else
				{
					//random attack if player is not too far up.
					if(cMath::RandRectf(0,1)<0.2f)//fHeight*2 > -fMax && 
						mpEnemy->ChangeState(STATE_ATTACK);
					else
						mpEnemy->ChangeState(STATE_FLEE);
				}
			}
			else
			{
				mpEnemy->ChangeState(STATE_ATTACK);
			}
			
			
		}
	}
	////////////////////////////////
	//Update path search
	else if(mbFreePlayerPath==false)
	{
		if( mbLostPlayer==false && mpMover->IsMoving()==false && mpEnemy->CanSeePlayer()==false)
		{
			mbLostPlayer = true;
			mfLostPlayerCount = mfMaxLostPlayerCount;
		}
		
		if(mbLostPlayer)
		{
			mpMover->GetCharBody()->Move(eCharDir_Forward,1.0f,afTimeStep);
			
			mfLostPlayerCount -= afTimeStep;
			if(mfLostPlayerCount <= 0 || mpMover->GetStuckCounter()>0.5f)
			{
				mpEnemy->ChangeState(STATE_IDLE);
			}
		}
	}
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Hunt::OnSeePlayer(const cVector3f &avPosition, float afChance)
{
	if(mbLostPlayer && afChance >= mpEnemyDog->mfHuntMinSeeChance)
	{
		mbLostPlayer = false;
		mfUpdatePathCount =0;
	}
}

//-----------------------------------------------------------------------

bool cGameEnemyState_Dog_Hunt::OnHearNoise(const cVector3f &avPosition, float afVolume)
{
	//////////////////////////////////
	//If player is lost the sound might be of help
	if(mbLostPlayer)
	{
		//Check if sound can be heard
		if(afVolume >= mpEnemyDog->mfHuntMinHearVolume)
		{
			//Check if a node is found near the sound.
			cAINode *pNode = mpMover->GetAINodeAtPosInRange(avPosition,0.0f,5.0f,true, 0.1f);
			if(pNode)
			{
				//Update last player postion.
				mbLostPlayer = false;
				mfUpdatePathCount =0;
				mpEnemy->SetLastPlayerPos(pNode->GetPosition());

				return true;
			}
		}
	}
	
	return false;
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Hunt::OnDraw()
{
	float fWantedSpeed = mpMover->GetCharBody()->GetMoveSpeed(eCharDir_Forward);
	float fRealSpeed = cMath::Vector3Dist(	mpMover->GetCharBody()->GetPosition(), 
											mpMover->GetCharBody()->GetLastPosition());
	fRealSpeed = fRealSpeed / (1.0f/60.0f);

	float fDist = mpMover->DistanceToChar2D(mpPlayer->GetCharacterBody());

	mpInit->mpDefaultFont->Draw(cVector3f(0,110,100),14,cColor(1,1,1,1),eFontAlign_Left,
		_W("LostPlayerCount: %f FreePath: %d NoPath: %d MaxStuck: %d Dist: %f / %f"),
															mfLostPlayerCount,mbFreePlayerPath,
															mbFoundNoPath,
															mlStuckAtMaxCount,
															fDist,
															mpEnemyDog->mfAttackDistance);
}

//-----------------------------------------------------------------------


//////////////////////////////////////////////////////////////////////////
// ATTACK STATE
//////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Attack::OnEnterState(iGameEnemyState *apPrevState)
{
	///////////////
	//Setup body
	mpEnemy->SetupBody();
	if(mpEnemyDog->mfAttackSpeed>0)
	{
		mpMover->GetCharBody()->SetMaxPositiveMoveSpeed(eCharDir_Forward,mpEnemyDog->mfAttackSpeed);
		mpMover->SetMaxTurnSpeed(10000.0f);

		//mpMover->SetMinBreakAngle(cMath::ToRad(140));
	}
	
	///////////////
	//Animation
	float fHeight = mpPlayer->GetCharacterBody()->GetPosition().y -
					mpMover->GetCharBody()->GetPosition().y;
	
	//Player is above
	if(fHeight > 0.1f)
		mpEnemy->PlayAnim("Attack",false,0.2f);
	else
		mpEnemy->PlayAnim("AttackLow",false,0.2f);

	///////////////
	//Other
	mpEnemyDog->PlaySound(mpEnemyDog->msAttackStartSound);

	mfDamageTimer = mpEnemyDog->mfAttackDamageTime;
	mfJumpTimer = mpEnemyDog->mfAttackJumpTime;
	mbAttacked = false;

	if(mpEnemy->GetOnAttackCallback() != "")
	{
		tString sCommand = mpEnemy->GetOnAttackCallback() + "(\""+mpEnemy->GetName()+"\")";
		mpInit->RunScriptCommand(sCommand);
	}
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Attack::OnLeaveState(iGameEnemyState *apNextState)
{
	mpEnemyDog->SetSkipSoundTriggerCount(2.0f);
	mpMover->ResetStuckCounter();

	
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Attack::OnUpdate(float afTimeStep)
{
	//Move forward
	if(mpEnemyDog->mfAttackSpeed>0)
	{
		if(mfJumpTimer <=0)
		{
			mpMover->MoveDirectToPos(mpPlayer->GetCharacterBody()->GetFeetPosition(),afTimeStep);
		}
		else
		{
			mpMover->TurnToPos(mpPlayer->GetCharacterBody()->GetFeetPosition());
			mfJumpTimer-= afTimeStep;
		}
	}

	if(mbAttacked) return;

	//////////////////////////////////////
	//Get the 2D distance to the player
	cVector3f vStart = mpPlayer->GetCharacterBody()->GetPosition();
	vStart.y =0;
	cVector3f vEnd = mpMover->GetCharBody()->GetPosition();
	vEnd.y = 0;
	float fDist2D = cMath::Vector3DistSqr(vStart,vEnd);
	float fMinRange = mpEnemyDog->mfAttackDamageRange;

	////////////////////////////////////////
	// Check if dog is in range of player
	if(fDist2D <=  fMinRange*fMinRange && mfDamageTimer <=0 )
	{
		if(mbAttacked == false)
		{
			cVector3f vPos =	mpMover->GetCharBody()->GetPosition() +
								mpMover->GetCharBody()->GetForward() * 
								mpEnemyDog->mfAttackDamageRange;

			cVector3f vRot = cVector3f(0,mpMover->GetCharBody()->GetYaw(),0);
			cMatrixf mtxOffset = cMath::MatrixRotate(vRot,eEulerRotationOrder_XYZ);
			mtxOffset.SetTranslation(vPos);
			
			eAttackTargetFlag target = eAttackTargetFlag_Player | eAttackTargetFlag_Bodies;
			
			mpInit->mpPlayer->mbDamageFromPos = true;
			mpInit->mpPlayer->mvDamagePos = mpMover->GetCharBody()->GetPosition();
			if(mpInit->mpAttackHandler->CreateShapeAttack(mpEnemyDog->GetAttackShape(),
										mtxOffset,
										mpMover->GetCharBody()->GetPosition(),
										cMath::RandRectf(	mpEnemyDog->mfAttackMinDamage,
															mpEnemyDog->mfAttackMaxDamage),
										
										mpEnemyDog->mfAttackMinMass, mpEnemyDog->mfAttackMaxMass,
										mpEnemyDog->mfAttackMinImpulse, mpEnemyDog->mfAttackMaxImpulse,
										
										mpEnemyDog->mlAttackStrength,

										target,NULL))
			{
				mpEnemyDog->PlaySound(mpEnemyDog->msAttackHitSound);
			}
			mpInit->mpPlayer->mbDamageFromPos = false;
			mbAttacked = true;
		}
	}
	else
	{
		mfDamageTimer -= afTimeStep;
	}

}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Attack::OnAnimationOver(const tString &asName)
{
	if(mpPlayer->GetHealth() <=0)
	{
		float fDist = mpMover->DistanceToChar2D(mpInit->mpPlayer->GetCharacterBody());
		if(fDist < 2.3f)
		{
			mpEnemy->SetTempFloat(60.0f);
			mpEnemy->ChangeState(STATE_EAT);
		}
		else
		{
			mpEnemy->ChangeState(STATE_FLEE);
		}
	}
	else
	{
		mpEnemy->ChangeState(STATE_FLEE);
	}
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Attack::OnPostSceneDraw()
{
	cCamera3D *pCamera = static_cast<cCamera3D*>(mpInit->mpGame->GetScene()->GetCamera());
	
	cVector3f vPos =	mpMover->GetCharBody()->GetPosition() +
						mpMover->GetCharBody()->GetForward() * 
						mpEnemyDog->mfAttackDamageRange;

	cVector3f vRot = cVector3f(0,mpMover->GetCharBody()->GetYaw(),0);
	cMatrixf mtxOffset = cMath::MatrixRotate(vRot,eEulerRotationOrder_XYZ);
	mtxOffset.SetTranslation(vPos);	
	
	
	cMatrixf mtxCollider = cMath::MatrixMul(pCamera->GetViewMatrix(),mtxOffset);

	mpInit->mpGame->GetGraphics()->GetLowLevel()->SetMatrix(eMatrix_ModelView,mtxCollider);

	cVector3f vSize = mpEnemyDog->GetAttackShape()->GetSize();
	mpInit->mpGame->GetGraphics()->GetLowLevel()->DrawBoxMaxMin(vSize*0.5f,vSize*-0.5f,
		cColor(1,0,1,1));
}

//-----------------------------------------------------------------------


//////////////////////////////////////////////////////////////////////////
// FLEE STATE
//////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Flee::OnEnterState(iGameEnemyState *apPrevState)
{
	//Animation
	mpEnemy->UseMoveStateAnimations();

	//Setup body
	mpEnemy->SetupBody();
	mpMover->GetCharBody()->SetMaxPositiveMoveSpeed(eCharDir_Forward,mpEnemyDog->mfHuntSpeed);
	mpMover->GetCharBody()->SetMaxNegativeMoveSpeed(eCharDir_Forward,-mpEnemyDog->mfFleeBackSpeed);
	
	float fPosMul = 1;
	if(apPrevState->GetId() == STATE_KNOCKDOWN) fPosMul = 4.0f;
	
	mbBackingFromBreakDoor = false;
	if(apPrevState->GetId() == STATE_BREAKDOOR)
		mbBackingFromBreakDoor = true;

	///////////////////////////////////////
	// The dog has just broken a door
	if(mbBackingFromBreakDoor)
	{
		mfBackAngle = mpMover->GetCharBody()->GetYaw();
		mbBackwards = true;

		mfTimer = mpEnemyDog->mfFleeBackTime;
		mfCheckBehindTime = 1.0f / 10.0f;
	}
	///////////////////////////////////////
	// Normal flee
	else
	{
		if(	(	apPrevState->GetId() == STATE_KNOCKDOWN || apPrevState->GetId() == STATE_HUNT ||
				cMath::RandRectf(0,1) < 0)//mpEnemyDog->mfFleePositionChance) 
			)
		{
			cAINode *pNode = mpMover->GetAINodeInRange(	mpEnemyDog->mfFleePositionMinDistance * fPosMul,
														mpEnemyDog->mfFleePositionMaxDistance * fPosMul);
			if(pNode) 
			{
				mpMover->MoveToPos(pNode->GetPosition());
			}
			else
			{
				mpEnemy->ChangeState(STATE_HUNT);
			}
			mfTimer = mpEnemyDog->mfFleePositionMaxTime;
			mbBackwards = false;
		}
		else if(cMath::RandRectf(0,1) < mpEnemyDog->mfFleeBackChance)
		{
			mfBackAngle = mpMover->GetCharBody()->GetYaw();
			mbBackwards = true;

			mfTimer = mpEnemyDog->mfFleeBackTime;
			mfCheckBehindTime = 1.0f / 10.0f;
		}
		else
		{
			mpEnemy->ChangeState(STATE_HUNT);
		}
	}
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Flee::OnLeaveState(iGameEnemyState *apNextState)
{
	mpMover->ResetStuckCounter();
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Flee::OnUpdate(float afTimeStep)
{
	mfTimer -= afTimeStep;

	if(mbBackwards)
	{
		if(mfCheckBehindTime <= 0)
		{
			mfCheckBehindTime = 1.0f / 20.0f;

			bool bHit = mpEnemy->GetGroundFinder()->GetGround(mpMover->GetCharBody()->GetPosition(),
												mpMover->GetCharBody()->GetForward() *-1,
												NULL, NULL, 1.9f);
			if(bHit)
			{
                if(mbBackingFromBreakDoor)
				{
					if(mlPreviousState == STATE_FLEE)
						mpEnemy->ChangeState(STATE_HUNT);
					else
						mpEnemy->ChangeState(mlPreviousState);
				}
				else
				{
					mpEnemy->ChangeState(STATE_HUNT);
				}
			}
		}
		else
		{
			mfCheckBehindTime -= afTimeStep;
		}

		if(mfTimer <=0)
		{
			if(mbBackingFromBreakDoor)
				mpEnemy->ChangeState(mlPreviousState);
			else
				mpEnemy->ChangeState(STATE_HUNT);
		}
		mpMover->GetCharBody()->Move(eCharDir_Forward,-1.0f,afTimeStep);
		mpMover->TurnToPos(mpInit->mpPlayer->GetCharacterBody()->GetFeetPosition());
	}
	else
	{
		//Move forward
		if(mpMover->IsMoving()==false || mpMover->GetStuckCounter() > 0.3f	|| mfTimer <=0)
		{
			//Check if there is any enemies nearaby and if anyone is allready fighting
			if(	mpEnemy->CheckForTeamMate(mpEnemyDog->mfCallBackupRange*1.5f,false) && 
				mpEnemy->CheckForTeamMate(8,true)==false)
			{
				float fPlayerDist = mpMover->DistanceToChar(mpInit->mpPlayer->GetCharacterBody());
				//Log("Dist: %f\n",fPlayerDist);
				if(fPlayerDist > 8)
				{
					mpEnemy->ChangeState(STATE_CALLBACKUP);
				}
				else
				{
					mpEnemy->ChangeState(STATE_HUNT);
				}
				//Log("Back from flee!!\n");
			}
			else
			{
				//if(mpInit->mpMusicHandler->AttackerExist(mpEnemy))
				{
					mpEnemy->ChangeState(STATE_HUNT);
				}
				//else
				//{
				//	mpEnemy->ChangeState(STATE_IDLE);
				//}
			}
		}
	}
}

//-----------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////
// CALL BACKUP STATE
//////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_CallBackup::OnEnterState(iGameEnemyState *apPrevState)
{
	//Animation
	mpEnemy->PlayAnim(mpEnemyDog->msCallBackupAnimation,false,0.2f);
	
	//Sound
	mpEnemyDog->PlaySound(mpEnemyDog->msCallBackupSound);
	
	//Iterate enemies and show them the player
	cVector3f vPostion = mpMover->GetCharBody()->GetFeetPosition();

	tGameEnemyIterator it = mpInit->mpMapHandler->GetGameEnemyIterator();
	while(it.HasNext())
	{
		iGameEnemy *pEnemy = it.Next();
		if(pEnemy->GetEnemyType() != mpEnemy->GetEnemyType()) continue;
		if(pEnemy == mpEnemy || pEnemy->IsActive()==false || pEnemy->GetHealth()<=0) continue;

		cGameEnemy_Dog *pDog = static_cast<cGameEnemy_Dog*>(pEnemy);

		float fDist = cMath::Vector3Dist(pDog->GetMover()->GetCharBody()->GetPosition(),
											vPostion);

		if(fDist <= mpEnemyDog->mfCallBackupRange)
		{
			pDog->ShowPlayer(mpEnemyDog->GetLastPlayerPos());
			break; // Call only for one dog backup!
		}
	}

	mpMover->Stop();
	mpMover->GetCharBody()->SetMoveSpeed(eCharDir_Forward,0);
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_CallBackup::OnLeaveState(iGameEnemyState *apNextState)
{
	mpMover->ResetStuckCounter();
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_CallBackup::OnUpdate(float afTimeStep)
{
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_CallBackup::OnAnimationOver(const tString &asName)
{
	mpEnemy->ChangeState(STATE_HUNT);
}

//-----------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////
// BREAK DOOR STATE
//////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_BreakDoor::OnEnterState(iGameEnemyState *apPrevState)
{
	//Setup body
	mpEnemy->SetupBody();
	if(mpEnemyDog->mfBreakDoorSpeed>0)
		mpMover->GetCharBody()->SetMaxPositiveMoveSpeed(eCharDir_Forward,mpEnemyDog->mfBreakDoorSpeed);


	//Animation
	mpEnemy->PlayAnim(mpEnemyDog->msBreakDoorAnimation,false,0.2f);

	mpEnemyDog->PlaySound(mpEnemyDog->msBreakDoorStartSound);

	mfDamageTimer = mpEnemyDog->mfBreakDoorDamageTime;
	mfStopMoveTimer = mpEnemyDog->mfBreakDoorDamageTime + 1.1f;
	mbAttacked = false;
	mbStopped = false;

	mlCount =0;
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_BreakDoor::OnLeaveState(iGameEnemyState *apNextState)
{
	mpEnemyDog->SetSkipSoundTriggerCount(2.0f);
	mpMover->ResetStuckCounter();
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_BreakDoor::OnUpdate(float afTimeStep)
{
	//Move forward
	if(mpEnemyDog->mfBreakDoorSpeed>0 && mlCount==0 && mbAttacked == false)
	{
		//Skip this for now
		//mpMover->GetCharBody()->Move(eCharDir_Forward,1.0f,afTimeStep);
	}

	if(mfDamageTimer <=0 )
	{
		if(!mbStopped)
		{
			mpMover->Stop();
			mbStopped = true;
		}
	}
	else
	{
		mfDamageTimer -= afTimeStep;
	}

	if(mfDamageTimer <=0 )
	{
		if(mbAttacked == false)
		{
			cVector3f vPos =	mpMover->GetCharBody()->GetPosition() +
								mpMover->GetCharBody()->GetForward() * 
								mpEnemyDog->mfBreakDoorDamageRange;

			cVector3f vRot = cVector3f(0,mpMover->GetCharBody()->GetYaw(),0);
			cMatrixf mtxOffset = cMath::MatrixRotate(vRot,eEulerRotationOrder_XYZ);
			mtxOffset.SetTranslation(vPos);

			eAttackTargetFlag target = eAttackTargetFlag_Player | eAttackTargetFlag_Bodies;

			if(mpInit->mpAttackHandler->CreateShapeAttack(mpEnemyDog->GetBreakDoorShape(),
											mtxOffset,
											mpMover->GetCharBody()->GetPosition(),
											cMath::RandRectf(	mpEnemyDog->mfBreakDoorMinDamage,
											mpEnemyDog->mfBreakDoorMaxDamage),

											mpEnemyDog->mfBreakDoorMinMass, mpEnemyDog->mfBreakDoorMaxMass,
											mpEnemyDog->mfBreakDoorMinImpulse, mpEnemyDog->mfBreakDoorMaxImpulse,

											mpEnemyDog->mlBreakDoorStrength,

											target,NULL))
			{
				mpEnemyDog->PlaySound(mpEnemyDog->msBreakDoorHitSound);

				cGameSwingDoor *pDoor = mpInit->mpAttackHandler->GetLastSwingDoor();
				if(pDoor)
				{
					/////////////////////////////
					//The door is unbreakable
					if(pDoor->GetToughness() - mpEnemyDog->mlBreakDoorStrength >= 4)
					{
						cMatrixf mtxDoor = pDoor->GetBody(0)->GetWorldMatrix();
						cMatrixf mtxInvDoor = cMath::MatrixInverse(mtxDoor);

						cVector3f vDoorForward = mtxInvDoor.GetForward();
						cVector3f vEnemyForward = mpMover->GetCharBody()->GetForward();

						if(cMath::Vector3Dot(vDoorForward,vEnemyForward) < 0)
						{
							mpEnemy->AddDoorBreakCount(2);//8);
							//mpInit->mpEffectHandler->GetSubTitle()->Add("Cannot break this door! On BAD side",4);
						}
						else
						{
							mpEnemy->AddDoorBreakCount(2);
							//Just continue hitting it since it is just barricaded.
							//mpInit->mpEffectHandler->GetSubTitle()->Add("Cannot break this door! On GOOD side",4);
						}
					}
					/////////////////////////////
					//The door is breakable
					else
					{
						mpEnemy->AddDoorBreakCount(2);
					}

				}

			}
			mbAttacked = true;
		}
	}
	else
	{
		mfDamageTimer -= afTimeStep;
	}

}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_BreakDoor::OnAnimationOver(const tString &asName)
{
	if(mlCount ==0)
	{
		if(mpEnemyDog->mbBreakDoorRiseAtEnd)
		{
			mpEnemy->PlayAnim("RiseRight",false,0.2f);
			mlCount++;
		}
		else
		{
			//mpEnemy->ChangeState(mlPreviousState);
			mpEnemy->ChangeState(STATE_FLEE);
			mpEnemy->GetState(STATE_FLEE)->SetPreviousState(mlPreviousState);
		}
	}
	else
	{
        //mpEnemy->ChangeState(mlPreviousState);
		mpEnemy->ChangeState(STATE_FLEE);
		mpEnemy->GetState(STATE_FLEE)->SetPreviousState(mlPreviousState);
	}
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_BreakDoor::OnPostSceneDraw()
{
	cCamera3D *pCamera = static_cast<cCamera3D*>(mpInit->mpGame->GetScene()->GetCamera());

	cVector3f vPos =	mpMover->GetCharBody()->GetPosition() +
						mpMover->GetCharBody()->GetForward() * 
						mpEnemyDog->mfBreakDoorDamageRange;

	cVector3f vRot = cVector3f(0,mpMover->GetCharBody()->GetYaw(),0);
	cMatrixf mtxOffset = cMath::MatrixRotate(vRot,eEulerRotationOrder_XYZ);
	mtxOffset.SetTranslation(vPos);	


	cMatrixf mtxCollider = cMath::MatrixMul(pCamera->GetViewMatrix(),mtxOffset);

	mpInit->mpGame->GetGraphics()->GetLowLevel()->SetMatrix(eMatrix_ModelView,mtxCollider);

	cVector3f vSize = mpEnemyDog->GetBreakDoorShape()->GetSize();
	mpInit->mpGame->GetGraphics()->GetLowLevel()->DrawBoxMaxMin(vSize*0.5f,vSize*-0.5f,
		cColor(1,0,1,1));
}

//-----------------------------------------------------------------------



//////////////////////////////////////////////////////////////////////////
// KNOCK DOWN STATE
//////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_KnockDown::OnEnterState(iGameEnemyState *apPrevState)
{
	//Animation
	mpEnemy->PlayAnim("Idle",true,0.7f);

	//Sound
	mpEnemy->PlaySound(mpEnemyDog->msKnockDownSound);

	//Setup body
	mpEnemy->SetupBody();

	//Go to rag doll
	mpEnemy->GetMeshEntity()->AlignBodiesToSkeleton(false);
	mpEnemy->GetMeshEntity()->SetSkeletonPhysicsActive(true);
	mpEnemy->GetMeshEntity()->Stop();

	mpEnemy->GetMover()->GetCharBody()->SetEntity(NULL);
	mpEnemy->GetMover()->GetCharBody()->SetActive(false);

	mpEnemy->GetMover()->Stop();

	mfTimer = 2.0f;
	mbCheckAnim = false;

	mlPrevToughness = mpEnemy->GetToughness();
	mpEnemy->SetToughness(12);
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_KnockDown::OnLeaveState(iGameEnemyState *apNextState)
{
	mpEnemy->SetToughness(mlPrevToughness);

	mpEnemy->GetMover()->GetCharBody()->SetEntity(mpEnemy->GetMeshEntity());
	mpEnemy->GetMover()->GetCharBody()->SetActive(true);
	mpMover->ResetStuckCounter();
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_KnockDown::OnUpdate(float afTimeStep)
{
	if(mbCheckAnim)
	{
		iCharacterBody *pCharBody = mpEnemy->GetMover()->GetCharBody();
		cBoundingVolume *pBV = pCharBody->GetBody()->GetBoundingVolume();
		
		////////////////////////////////////////////////
		//Add a force to all objects around dog.
		iPhysicsWorld *pWorld = mpInit->mpGame->GetScene()->GetWorld3D()->GetPhysicsWorld();

		std::list<iPhysicsBody*> lstBodies;
		cPhysicsBodyIterator bodyIt = pWorld->GetBodyIterator();
		while(bodyIt.HasNext())
		{
			lstBodies.push_back(bodyIt.Next());
		}

		//////////////////////////
		//Force Iteration
		std::list<iPhysicsBody*>::iterator it = lstBodies.begin();
		for(; it != lstBodies.end(); ++it)
		{
			iPhysicsBody *pBody = *it;

			if(pBody->GetCollideCharacter()==false) continue;
			if(pBody->IsActive()==false) continue;
			if(pBody == pCharBody->GetBody()) continue;

			if(cMath::CheckCollisionBV(*pBody->GetBoundingVolume(), *pBV))
			{
				cVector3f vDir = pBody->GetWorldPosition() - pCharBody->GetPosition();
				float fLength = vDir.Length();
				//vDir.y *= 0.1f;
				//if(vDir.x ==0 && vDir.z ==0) vDir.x = 0.3f;
				vDir.Normalise();
				
				if(fLength==0) fLength = 0.001f;
				float fForce = (1 / fLength) * 2;
				if(fForce > 300) fForce = 300;
				if(	mpInit->mpPlayer->GetState() == ePlayerState_Grab &&
					mpInit->mpPlayer->GetPushBody() == pBody)
				{
					fForce *= 40;
				}
				
				if(pBody->IsCharacter())
				{
					pBody->GetCharacterBody()->AddForce(vDir * fForce *10 *
											pBody->GetCharacterBody()->GetMass());
				}
				else
				{
					pBody->AddForce(vDir * fForce * pBody->GetMass());
				}
			}
		}
	}
	else
	{
		mfTimer -= afTimeStep;

		if(mfTimer <=0)
		{
			//Get the forward vector from root bone (the right vector)
			cNodeIterator StateIt = mpEnemy->GetMeshEntity()->GetRootNode()->GetChildIterator();
			cBoneState *pBoneState = static_cast<cBoneState*>(StateIt.Next());
			
			cVector3f vRight = cMath::MatrixInverse(pBoneState->GetWorldMatrix()).GetForward();

			//Play animation and fade physics
			float fFadeTime = 1.0f;
			mbCheckAnim = true;
			
			mpEnemy->GetMeshEntity()->Stop();
			if(cMath::Vector3Dot(vRight,cVector3f(0,1,0))<0)
				mpEnemy->PlayAnim("RiseRight",false,fFadeTime);
			else
				mpEnemy->PlayAnim("RiseLeft",false,fFadeTime);

			mpEnemy->GetMeshEntity()->FadeSkeletonPhysicsWeight(fFadeTime);

			//Calculate values
			cVector3f vPosition;
			cVector3f vAngles;
			cMatrixf mtxTransform = mpEnemy->GetMeshEntity()->CalculateTransformFromSkeleton(&vPosition,&vAngles);
			
			//Seems to work better...
			vPosition = mpEnemy->GetMeshEntity()->GetBoundingVolume()->GetWorldCenter();
			cVector3f vGroundPos = vPosition;
			
			bool bFoundGround = mpEnemy->GetGroundFinder()->GetGround(vPosition,cVector3f(0,-1,0),&vGroundPos,NULL);

			//Log("Found ground: %d | %s -> %s\n",bFoundGround,vPosition.ToString().c_str(),
			//									vGroundPos.ToString().c_str());
			
			//Set body
			iCharacterBody *pCharBody = mpEnemy->GetMover()->GetCharBody();
			
			//vGroundPos -= pCharBody->GetEntityOffset().GetTranslation();
			float fYAngle = vAngles.y - mpEnemy->GetModelOffsetAngles().y;
			//cVector3f vAdd = cVector3f(0,0,pCharBody->GetEntityOffset().GetTranslation().z);
			//vAdd = cMath::MatrixMul(cMath::MatrixRotateY(fYAngle),vAdd);
			//vGroundPos += vAdd;
			pCharBody->SetFeetPosition(vGroundPos);
			pCharBody->SetYaw(fYAngle);
			pCharBody->SetEntity(mpEnemy->GetMeshEntity());
			pCharBody->SetActive(true);
			//pCharBody->Update(1.0f / 60.0f);
			//pCharBody->SetActive(false);
			
			for(int i=0; i<3; ++i)
			{
				pCharBody->Update(1.0f/60.0f);

				mpEnemy->GetMeshEntity()->UpdateLogic(1.0f/60.0f);
				mpEnemy->GetMeshEntity()->UpdateGraphics(NULL,1.0f/60.0f,NULL);
			}
		}
	}
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_KnockDown::OnAnimationOver(const tString &asName)
{
	iCharacterBody *pCharBody = mpEnemy->GetMover()->GetCharBody();

	if(	mpEnemy->CheckForTeamMate(mpEnemyDog->mfCallBackupRange*1.5f,false) && 
		mpEnemy->CheckForTeamMate(14,true)==false)
	{
		pCharBody->SetActive(true);
		mpEnemy->ChangeState(STATE_FLEE);
	}
	else
	{
		pCharBody->SetActive(true);
		//mpEnemy->ChangeState(STATE_HUNT);
		mpEnemy->ChangeState(STATE_FLEE);
	}
}

//-----------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////
// DEAD STATE
//////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Dead::OnEnterState(iGameEnemyState *apPrevState)
{
	//Animation
	mpEnemy->PlayAnim("Idle",true,0.7f);

	//Sound
	if(mpEnemy->IsLoading()==false)
		mpEnemy->PlaySound(mpEnemyDog->msDeathSound);

	//Setup body
	mpEnemy->SetupBody();

	//Go to ragdoll
	if(mpEnemy->IsLoading()==false)
		mpEnemy->GetMeshEntity()->AlignBodiesToSkeleton(false);
	
	mpEnemy->GetMeshEntity()->SetSkeletonPhysicsActive(true);
	mpEnemy->GetMeshEntity()->Stop();

	mpEnemy->GetMover()->GetCharBody()->SetEntity(NULL);
	mpEnemy->GetMover()->GetCharBody()->SetActive(false);

	mpEnemy->GetMover()->Stop();

	mpInit->mpMusicHandler->RemoveAttacker(mpEnemy);
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Dead::OnLeaveState(iGameEnemyState *apNextState)
{
}

//-----------------------------------------------------------------------

void cGameEnemyState_Dog_Dead::OnUpdate(float afTimeStep)
{
}

//-----------------------------------------------------------------------


//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------

cGameEnemy_Dog::cGameEnemy_Dog(cInit *apInit,const tString& asName,TiXmlElement *apGameElem) : iGameEnemy(apInit,asName,apGameElem)
{
	LoadBaseProperties(apGameElem);
	
	//////////////////////////////
	//Special properties 

	mfLengthBodyToAss = cString::ToFloat(apGameElem->Attribute("LengthBodyToAss"),1.5f);
	
	mfMinKnockDamage = cString::ToFloat(apGameElem->Attribute("MinKnockDamage"),0);
	mfCertainKnockDamage = cString::ToFloat(apGameElem->Attribute("CertainKnockDamage"),0);

		
	//////////////////////////////
	//State properties
	mfIdleFOV = cMath::ToRad(cString::ToFloat(apGameElem->Attribute("IdleFOV"),0));
	msIdleFoundPlayerSound = cString::ToString(apGameElem->Attribute("IdleFoundPlayerSound"),"");
	mfIdleMinSeeChance = cString::ToFloat(apGameElem->Attribute("IdleMinSeeChance"),0);
	mfIdleMinHearVolume = cString::ToFloat(apGameElem->Attribute("IdleMinHearVolume"),0);
	msIdleSound = cString::ToString(apGameElem->Attribute("IdleSound"),"");
	mfIdleSoundMinInteraval = cString::ToFloat(apGameElem->Attribute("IdleSoundMinInteraval"),0);
	mfIdleSoundMaxInteraval = cString::ToFloat(apGameElem->Attribute("IdleSoundMaxInteraval"),0);
	mfIdleCallBackupChance = cString::ToFloat(apGameElem->Attribute("IdleCallBackupChance"),0);
	mvPreloadSounds.push_back(msIdleSound);

	msInvestigateSound = cString::ToString(apGameElem->Attribute("InvestigateSound"),"");
	mvPreloadSounds.push_back(msInvestigateSound);

	msAttentionSound = cString::ToString(apGameElem->Attribute("AttentionSound"),"");
	mfAttentionTime = cString::ToFloat(apGameElem->Attribute("AttentionTime"),0);
	mfAttentionMinDist = cString::ToFloat(apGameElem->Attribute("AttentionMinDist"),0);
	mvPreloadSounds.push_back(msAttentionSound);

	mfHuntFOV = cMath::ToRad(cString::ToFloat(apGameElem->Attribute("HuntFOV"),0));
	mfHuntSpeed = cString::ToFloat(apGameElem->Attribute("HuntSpeed"),0);
	mfHuntForLostPlayerTime = cString::ToFloat(apGameElem->Attribute("HuntForLostPlayerTime"),0);
	mfHuntMinSeeChance = cString::ToFloat(apGameElem->Attribute("IdleMinSeeChance"),0);
	mfHuntMinHearVolume = cString::ToFloat(apGameElem->Attribute("IdleMinHearVolume"),0);

	mfAttackDistance = cString::ToFloat(apGameElem->Attribute("AttackDistance"),0);
	mfAttackSpeed = cString::ToFloat(apGameElem->Attribute("AttackSpeed"),0);
	mfAttackJumpTime = cString::ToFloat(apGameElem->Attribute("AttackJumpTime"),0);
	mfAttackDamageTime = cString::ToFloat(apGameElem->Attribute("AttackDamageTime"),0);
	mvAttackDamageSize = cString::ToVector3f(apGameElem->Attribute("AttackDamageSize"),0);
	mfAttackDamageRange = cString::ToFloat(apGameElem->Attribute("AttackDamageRange"),0);
	mfAttackMinDamage = cString::ToFloat(apGameElem->Attribute("AttackMinDamage"),0);
	mfAttackMaxDamage = cString::ToFloat(apGameElem->Attribute("AttackMaxDamage"),0);
	msAttackStartSound = cString::ToString(apGameElem->Attribute("AttackStartSound"),"");
	msAttackHitSound = cString::ToString(apGameElem->Attribute("AttackHitSound"),"");
	mfAttackMinMass = cString::ToFloat(apGameElem->Attribute("AttackMinMass"),0);
	mfAttackMaxMass = cString::ToFloat(apGameElem->Attribute("AttackMaxMass"),0);
	mfAttackMinImpulse = cString::ToFloat(apGameElem->Attribute("AttackMinImpulse"),0);
	mfAttackMaxImpulse = cString::ToFloat(apGameElem->Attribute("AttackMaxImpulse"),0);
	mlAttackStrength = cString::ToInt(apGameElem->Attribute("AttackStrength"),0);
	mvPreloadSounds.push_back(msAttackStartSound);
	mvPreloadSounds.push_back(msAttackHitSound);

	msBreakDoorAnimation = cString::ToString(apGameElem->Attribute("BreakDoorAnimation"),"");
	mfBreakDoorSpeed = cString::ToFloat(apGameElem->Attribute("BreakDoorSpeed"),0);
	mfBreakDoorDamageTime = cString::ToFloat(apGameElem->Attribute("BreakDoorDamageTime"),0);
	mvBreakDoorDamageSize = cString::ToVector3f(apGameElem->Attribute("BreakDoorDamageSize"),0);
	mfBreakDoorDamageRange = cString::ToFloat(apGameElem->Attribute("BreakDoorDamageRange"),0);
	mfBreakDoorMinDamage = cString::ToFloat(apGameElem->Attribute("BreakDoorMinDamage"),0);
	mfBreakDoorMaxDamage = cString::ToFloat(apGameElem->Attribute("BreakDoorMaxDamage"),0);
	msBreakDoorStartSound = cString::ToString(apGameElem->Attribute("BreakDoorStartSound"),"");
	msBreakDoorHitSound = cString::ToString(apGameElem->Attribute("BreakDoorHitSound"),"");
	mfBreakDoorMinMass = cString::ToFloat(apGameElem->Attribute("BreakDoorMinMass"),0);
	mfBreakDoorMaxMass = cString::ToFloat(apGameElem->Attribute("BreakDoorMaxMass"),0);
	mfBreakDoorMinImpulse = cString::ToFloat(apGameElem->Attribute("BreakDoorMinImpulse"),0);
	mfBreakDoorMaxImpulse = cString::ToFloat(apGameElem->Attribute("BreakDoorMaxImpulse"),0);
	mlBreakDoorStrength = cString::ToInt(apGameElem->Attribute("BreakDoorStrength"),0);
	mbBreakDoorRiseAtEnd = cString::ToBool(apGameElem->Attribute("BreakDoorRiseAtEnd"),false);
	mvPreloadSounds.push_back(msBreakDoorStartSound);
	mvPreloadSounds.push_back(msBreakDoorHitSound);

	msKnockDownSound = cString::ToString(apGameElem->Attribute("KnockDownSound"),"");
	mvPreloadSounds.push_back(msKnockDownSound);

	msDeathSound = cString::ToString(apGameElem->Attribute("DeathSound"),"");
	mvPreloadSounds.push_back(msDeathSound);

	mfFleePositionChance = cString::ToFloat(apGameElem->Attribute("FleePositionChance"),0);
	mfFleePositionMaxTime = cString::ToFloat(apGameElem->Attribute("FleePositionMaxTime"),0);
	mfFleePositionMinDistance = cString::ToFloat(apGameElem->Attribute("FleePositionMinDistance"),0);
	mfFleePositionMaxDistance = cString::ToFloat(apGameElem->Attribute("FleePositionMaxDistance"),0);
	mfFleeBackChance = cString::ToFloat(apGameElem->Attribute("FleeBackChance"),0);
	mfFleeBackTime = cString::ToFloat(apGameElem->Attribute("FleeBackTime"),0);
	mfFleeBackSpeed = cString::ToFloat(apGameElem->Attribute("FleeBackSpeed"),0);

	msCallBackupAnimation = cString::ToString(apGameElem->Attribute("CallBackupAnimation"),"");
	msCallBackupSound = cString::ToString(apGameElem->Attribute("CallBackupSound"),"");
	mfCallBackupRange = cString::ToFloat(apGameElem->Attribute("CallBackupRange"),0);
	mvPreloadSounds.push_back(msCallBackupSound);

	mfEatFOV = cMath::ToRad(cString::ToFloat(apGameElem->Attribute("EatFOV"),0));
	mfEatMinSeeChance = cString::ToFloat(apGameElem->Attribute("EatMinSeeChance"),0);
	mfEatMinHearVolume = cString::ToFloat(apGameElem->Attribute("EatMinHearVolume"),0);


	//////////////////////////////
	//Set up states
	AddState(hplNew( cGameEnemyState_Dog_Idle,(STATE_IDLE,mpInit,this)) );
	AddState(hplNew( cGameEnemyState_Dog_Hunt,(STATE_HUNT,mpInit,this)) );
	AddState(hplNew( cGameEnemyState_Dog_Attack,(STATE_ATTACK,mpInit,this)) );
	AddState(hplNew( cGameEnemyState_Dog_Flee,(STATE_FLEE,mpInit,this)) );
	AddState(hplNew( cGameEnemyState_Dog_KnockDown,(STATE_KNOCKDOWN,mpInit,this)) );
	AddState(hplNew( cGameEnemyState_Dog_Dead,(STATE_DEAD,mpInit,this)) );
	AddState(hplNew( cGameEnemyState_Dog_Patrol,(STATE_PATROL,mpInit,this)) );
	AddState(hplNew( cGameEnemyState_Dog_Investigate,(STATE_INVESTIGATE,mpInit,this)) );
	AddState(hplNew( cGameEnemyState_Dog_BreakDoor,(STATE_BREAKDOOR,mpInit,this)) );
	AddState(hplNew( cGameEnemyState_Dog_CallBackup,(STATE_CALLBACKUP,mpInit,this)) );
	AddState(hplNew( cGameEnemyState_Dog_MoveTo,(STATE_MOVETO,mpInit,this)) );
	AddState(hplNew( cGameEnemyState_Dog_Eat,(STATE_EAT,mpInit,this)) );
	AddState(hplNew( cGameEnemyState_Dog_Attention,(STATE_ATTENTION,mpInit,this)) );
}

//-----------------------------------------------------------------------

cGameEnemy_Dog::~cGameEnemy_Dog()
{

}

//-----------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------

void cGameEnemy_Dog::OnLoad()
{
	//Create attack shape
	iPhysicsWorld *pPhysicsWorld = mpInit->mpGame->GetScene()->GetWorld3D()->GetPhysicsWorld();
	mpAttackShape = pPhysicsWorld->CreateBoxShape(mvAttackDamageSize,NULL);
	mpBreakDoorShape = pPhysicsWorld->CreateBoxShape(mvBreakDoorDamageSize,NULL);
	
	//Set up shape
	ChangeState(STATE_IDLE);
}

//-----------------------------------------------------------------------

void cGameEnemy_Dog::OnUpdate(float afTimeStep)
{
	if(IsActive()==false) return;
	
	///////////////////////////////////
	//Regenerate health:
	if(mfHealth > 0)
	{
		if(	mpInit->mDifficulty != eGameDifficulty_Easy &&
			mfHealth <= mfMaxHealth *0.5f)
		{
			mfHealth += afTimeStep * (10.0f / 60.0f); //10 heal units / min
		}
	}

	///////////////////////////////////
	//Check for ass in wall
	if(mfHealth >0 && mpMover->GetCharBody()->IsActive())
	{
		float fMaxMove = afTimeStep * 2;
		static int lAssCount =0;
		lAssCount++;
		if(lAssCount % 2 == 0)
		{
			iCharacterBody *pCharBody = mpMover->GetCharBody();
			
			cVector3f vPos, vNormal;
			mFindGround.GetGround(pCharBody->GetPosition(), pCharBody->GetForward()*-1,
									&vPos,&vNormal,mfLengthBodyToAss);
			float fDist = cMath::Vector3Dist(pCharBody->GetPosition(), vPos);
			if(fDist < mfLengthBodyToAss)
			{
				float fAdd = mfLengthBodyToAss - fDist;
				if(fAdd > fMaxMove) fAdd = fMaxMove;
				
				cVector3f vAdd = pCharBody->GetForward() * fAdd;
				pCharBody->SetPosition(pCharBody->GetPosition() + vAdd);
			}
		}
	}
}

//-----------------------------------------------------------------------

void cGameEnemy_Dog::ShowPlayer(const cVector3f& avPlayerFeetPos)
{
	if(	mlCurrentState == STATE_IDLE || mlCurrentState == STATE_PATROL || 
		mlCurrentState == STATE_INVESTIGATE)
	{
		mvLastPlayerPos = avPlayerFeetPos;
		ChangeState(STATE_HUNT);
	}
}

//-----------------------------------------------------------------------

bool cGameEnemy_Dog::MoveToPos(const cVector3f& avFeetPos)
{
	if(	mlCurrentState == STATE_IDLE || mlCurrentState == STATE_PATROL)
	{
		SetTempPosition(avFeetPos);
		ChangeState(STATE_MOVETO);
		return true;
	}
	else
	{
		return false;
	}
}

//-----------------------------------------------------------------------

bool cGameEnemy_Dog::IsFighting()
{
	if( mfHealth <= 0 || IsActive()==false) return false;
	if(	mlCurrentState == STATE_IDLE || mlCurrentState == STATE_PATROL || 
		mlCurrentState == STATE_INVESTIGATE) return false;

	return true;
}

//-----------------------------------------------------------------------
